package com.codechen.scaffold.admin.service.impl;

import com.codechen.scaffold.admin.service.IFileService;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

/**
 * @author：wuweihong
 * @date 2023-05-11 16:01
 * @description 文件接口实现类
 */
@Service
public class FileServiceImpl implements IFileService {

    @Value("${file.store.path}")
    private String path;

    private Path getPath() {
        return Paths.get(this.path);
    }

    @Override
    public void init() {
        try {
            Files.createDirectories(getPath());
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Could not initialize folder for upload!");
        }
    }

    @Override
    public String sava(MultipartFile file) {
        try {
            // 读取文件输入流并计算 MD5
            String md5 = DigestUtils.md5Hex(file.getInputStream());
            // 获取原始文件后缀
            String originalFilename = file.getOriginalFilename();
            String fileExtension = "";
            int dotIndex = originalFilename.lastIndexOf('.');
            if (dotIndex > 0) {
                fileExtension = originalFilename.substring(dotIndex);
            }
            // 构建新的文件名（MD5 + 后缀）
            String newFileName = md5 + fileExtension;
            if (Files.exists(getPath().resolve(newFileName))) {
                return newFileName;
            }
            Files.copy(file.getInputStream(), getPath().resolve(newFileName));
            return newFileName;
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Could not store the file. Error:" + e.getMessage());
        }
    }

    @Override
    public Resource load(String fileName) {
        Path resolve = getPath().resolve(fileName);
        try {
            UrlResource resource = null;
            resource = new UrlResource(resolve.toUri());
            if (resource.exists() || resource.isReadable()) {
                return resource;
            } else {
                throw new RuntimeException("could not read the file.");
            }
        } catch (MalformedURLException e) {
//            e.printStackTrace();
            throw new RuntimeException("Error:" + e.getMessage());
        }

    }

    @Override
    public Stream<Path> load() {
        try {
            return Files.walk(getPath(), 1)
                    .filter(path1 -> !path1.equals(this.path))
                    .map(getPath()::relativize);
        } catch (IOException e) {
//            e.printStackTrace();
            throw new RuntimeException("could not load the files.");
        }
    }

    @Override
    public void clear() {
        FileSystemUtils.deleteRecursively(getPath().toFile());
    }
}
